/*
 * Copyright 2013 Alibaba.com All right reserved. This software is the
 * confidential and proprietary information of Alibaba.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Alibaba.com.
 */
package com.madding.shared.encrypt.cert.bc.main;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.madding.shared.encrypt.cert.bc.model.CertModel;
import com.madding.shared.encrypt.cert.bc.util.KeyPairUtil;
import com.madding.shared.encrypt.cert.exception.TDCertException;
import com.madding.shared.encrypt.cert.gen.SingleX509V1Creator;

/**
 * 类CertificateFactory.java的实现描述：证书创建工厂类
 * 
 * @author madding.lip Dec 5, 2013 10:05:31 AM
 */
public class SingleCertCreator {

    public static final long   ROOT_CERT_INDATE   = 20 * 365 * 24 * 60L * 60 * 1000L;
    public static final long   CLIENT_CERT_INDATE = 5 * 365 * 24 * 60L * 60 * 1000L;

    public static final String ISSUE_STRING       = "C=CN,  ST=ZheJiang,  L=HangZhou,  O=Alibaba,  OU=Inc,  CN=trustDevice,  Email=alilang@alibaba-inc.com";
    public static final String SUBJECT_Pattern    = "C=CN,  ST=ZheJiang,  L=HangZhou,  O=Alibaba,  OU=Inc,  CN={0},  Email={1}";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    
    public static void create() throws TDCertException {
        KeyPair pair = KeyPairUtil.generateRSAKeyPair();

        // create the input stream
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();

        CertModel certModel = new CertModel();
        certModel.setNotBefore(new Date(System.currentTimeMillis()));
        certModel.setNotAfter(new Date(System.currentTimeMillis() + ROOT_CERT_INDATE));

        try {
            bOut.write(SingleX509V1Creator.generateV1Certificate(certModel, pair).getEncoded());
            bOut.close();
            InputStream in = new ByteArrayInputStream(bOut.toByteArray());
            CertificateFactory fact = CertificateFactory.getInstance("X.509", "BC");
            X509Certificate x509Cert = (X509Certificate) fact.generateCertificate(in);

            System.out.println("issuer: " + x509Cert.getIssuerX500Principal());
        } catch (CertificateEncodingException e) {
            throw new TDCertException(e);
        } catch (IOException e) {
            throw new TDCertException(e);
        } catch (TDCertException e) {
            throw new TDCertException(e);
        } catch (CertificateException e) {
            throw new TDCertException(e);
        } catch (NoSuchProviderException e) {
            throw new TDCertException(e);
        }
    }

    public static void main(String[] args) throws TDCertException {
        SingleCertCreator.create();
    }
}
